package server.handler.friendHandler;

import com.alibaba.fastjson.JSONObject;
import common.EnvelopeMessage;
import common.messages.PrivateChatMessage;
import server.dao.MessageDao;
import server.session.Session;
import server.handler.SimpleHandler;
import server.session.SessionManager;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Base64;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class PrivateChatHandler implements SimpleHandler {

    private static final Path BASE_DIR = Paths.get("data/uploads/");
    private static final Map<String, OutputStream> streamMap = new ConcurrentHashMap<>();

    @Override
    public void handle(EnvelopeMessage msg, Session session) {
        JSONObject body = (JSONObject) msg.getBody();
        String type = body.getString("messageType");

        PrivateChatMessage chatMsg = JSONObject.toJavaObject(body, PrivateChatMessage.class);

        if ("fileChunk".equals(type)) {
            String fileUUID = body.getString("fileUUID");
            String fileName = body.getString("fileName");
            int chunkIndex = body.getIntValue("chunkIndex");
            int totalChunks = body.getIntValue("totalChunks");
            String base64Data = body.getString("fileChunk");

            try {
                Path userDir = BASE_DIR.resolve("user_" + chatMsg.getReceiverId());
                Files.createDirectories(userDir);


                Path targetFile = userDir.resolve(fileUUID + "_" + fileName);

                OutputStream out = streamMap.computeIfAbsent(fileUUID, id -> {
                    try {
                        return new BufferedOutputStream(Files.newOutputStream(
                                targetFile, StandardOpenOption.CREATE, StandardOpenOption.APPEND
                        ));
                    } catch (IOException e) {
                        e.printStackTrace();
                        return null;
                    }
                });

                if (out != null) {
                    byte[] chunkBytes = Base64.getDecoder().decode(base64Data);
                    out.write(chunkBytes);
                    out.flush();
                }
                if (chunkIndex == totalChunks - 1) {
                    OutputStream outToClose = streamMap.remove(fileUUID);
                    if (outToClose != null) outToClose.close();

                    chatMsg.setMessageType("file");
                    chatMsg.setMessage(targetFile.toString());
                    chatMsg.setFileName(fileName);

                    new MessageDao().savePrivateMessage(chatMsg);

                    body.put("messageType", "file");
                    body.put("message", targetFile.toString());
                    body.put("fileName", fileName);
                } else {
                    return;
                }

            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
        } else if("text".equals(type)) {
            new MessageDao().savePrivateMessage(chatMsg);
        }

        EnvelopeMessage back = new EnvelopeMessage("chat", "private", body);
        Session toSession = SessionManager.getSession(chatMsg.getReceiverId());
        if (toSession != null) {
            toSession.send(JSONObject.toJSONString(back));
        } else {
            System.out.println("用户不在线，暂不推送");
        }
    }

}
